﻿using System.Collections.Generic;
using System.Linq;
using Foothill.Model;
using System;

namespace Foothill.Service.AdService
{
    public class SearchResultStatsCalculator : ISearchResultStatsCalculator
    {
        private IStatsGroupManager _mileageStatsGroupManager;
        private IStatsGroupManager _yearAgeStatsGroupManager;

        public SearchResultStatsCalculator()
        {
            _mileageStatsGroupManager = new MileageStatsGroupManager();
            _yearAgeStatsGroupManager = new YearStatsGroupManager();
        }
        
        public IList<StatsItem> GetMakeStatsList(IList<ForSaleAd> resultList)
        {
            IList<StatsItem> result = new List<StatsItem>();
            var groups = resultList.GroupBy(c => new { c.MakeId, c.MakeName });

            foreach (var group in groups)
            {
                result.Add(new StatsItem { GroupId = group.Key.MakeId, GroupName = group.Key.MakeName, Count = group.ToList().Count });
            }

            return result;
        }

        public IList<StatsItem> GetCityStatsList(IList<ForSaleAd> resultList)
        {
            IList<StatsItem> result = new List<StatsItem>();
            var groups = resultList.GroupBy(c => new { c.CityId, c.CityName });

            foreach (var group in groups)
            {
                result.Add(new StatsItem { GroupId = group.Key.CityId, GroupName = group.Key.CityName, Count = group.ToList().Count });
            }

            return result;
        }

        public IList<StatsItem> GetConditionStatsList(IList<ForSaleAd> resultList)
        {
            IList<StatsItem> result = new List<StatsItem>();
            var groups = resultList.GroupBy(c => new { c.VehicleConditionId, c.VehicleConditionName });

            foreach (var group in groups)
            {
                result.Add(new StatsItem { GroupId = group.Key.VehicleConditionId, GroupName = group.Key.VehicleConditionName, Count = group.ToList().Count });
            }

            return result;
        }

        public IList<StatsItem> GetListingTypeStatsList(IList<ForSaleAd> resultList)
        {
            IList<StatsItem> result = new List<StatsItem>();
            var groups = resultList.GroupBy(c => new { c.ListingTypeId, c.ListingTypeString });

            foreach (var group in groups)
            {
                result.Add(new StatsItem { GroupId = group.Key.ListingTypeId, GroupName = group.Key.ListingTypeString, Count = group.ToList().Count });
            }

            return result;
        }

        public IList<StatsItem> GetTransmissionTypeStatsList(IList<ForSaleAd> resultList)
        {
            IList<StatsItem> result = new List<StatsItem>();
            var groups = resultList.GroupBy(c => new { c.TransmissionTypeId, c.TransmissionTypeName });

            foreach (var group in groups)
            {
                result.Add(new StatsItem { GroupId = group.Key.TransmissionTypeId, GroupName = group.Key.TransmissionTypeName, Count = group.ToList().Count });
            }

            return result;
        }

        public void GetMileageStatsList(IList<ForSaleAd> resultList, out IList<StatsItem> mileAgeStats, out IList<StatsItem> yearAgeStats)
        {
            mileAgeStats = new List<StatsItem>();
            yearAgeStats = new List<StatsItem>();

            foreach (ForSaleAd post in resultList)
            {
                ProcessOnePost(post, mileAgeStats, _mileageStatsGroupManager);
                ProcessOnePost(post, yearAgeStats, _yearAgeStatsGroupManager);
            }

            mileAgeStats = mileAgeStats.OrderBy(p => p.GroupId).ToList();
            yearAgeStats = yearAgeStats.OrderBy(p => p.GroupId).ToList();
        }

        private void ProcessOnePost(ForSaleAd post, IList<StatsItem> statsList, IStatsGroupManager statsManager)
        {
            Tuple<int, string> group = statsManager.DetermineGroup(post);

            StatsItem groupStats = statsList.FirstOrDefault(p => p.GroupId == group.Item1);

            if (groupStats != null)
            {
                // an existing group
                groupStats.Count++;
            }
            else
            {
                // add a new group
                statsList.Add(new StatsItem { GroupId = group.Item1, GroupName = group.Item2, Count = 1 });
            }
        }
    }
}
